﻿
namespace Patterns4Net.PatternEnforcer.Core.Patterns
{
    using Patterns4Net.Core.CecilExtensions;
    using Patterns4Net.Core.Patterns;

    [PatternCheckerExport(typeof(FactoryMethod))]
    public class FactoryMethodChecker : FluentPatternChecker<FactoryMethod>
    {
        public FactoryMethodChecker()
        {
            // declared in non sealed class or iface
            this.Type(pattern => pattern.TargetMethod.DeclaringType)
                .Check(
                    type => type.IsInterface || type.IsSealed == false,
                    type => string.Format(ErrorMessages.FactoryMethodCannotBeInSealedType, type.Name));

            // factory method should be virtual and should not return void
            this.Method(pattern => pattern.TargetMethod)
                .Check(
                    method => method.IsOverriddeable(),
                    method => string.Format(ErrorMessages.FactoryMethodCannotBeSealed, method.Name, method.DeclaringType.Name))
                .Check(
                    method => method.MethodReturnType.IsVoid() == false,
                    method => string.Format(ErrorMessages.FactoryMethodCannotBeVoid, method.Name, method.DeclaringType.Name));
        }
    }
}
